package com.example.demo.service;

import lombok.Getter;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.impl.DSL;
import org.jooq.impl.TableImpl;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.util.List;

@Getter
public class QueryService<E> {

    @Autowired private DSLContext ctx;
    private final Class<E> clazz = this.getEntityClass();
    private final TableImpl<?> table = this.getTableInstance();

    private Class<E> getEntityClass() {
        ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
        return (Class<E>) parameterizedType.getActualTypeArguments()[0];
    }

    private TableImpl<?> getTableInstance() {
        try {
            Class<?> tableClass = Class.forName("%s$Table".formatted(clazz.getName()));
            Constructor<?> constructor = tableClass.getDeclaredConstructor();
            constructor.setAccessible(true);
            return (TableImpl<?>) constructor.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("无法实例化table", e);
        }
    }

    public List<E> selectList(Condition condition) {
        return ctx.selectFrom(table).where(condition).fetchInto(clazz);
    }

    public E selectOne(Condition condition) {
        return ctx.selectFrom(table).where(condition).limit(1).fetchOneInto(clazz);
    }

    public E selectById(Long id) {
        return this.selectOne(DSL.field("id", Long.class).eq(id));
    }
}
